<?php

class TreeModel extends aBaseModel
{
	protected $dbColumns = array(
		'lw_tree' => array(
			'growthValue',
			'growthTimes',
			'fruitgrowthValue',
			'friutNum',
			'isDied',
			'isDry',
			'canBeCut',
		),
	);
	
	/**
	 * 当前可砍伐次数
	 * @var int
	 */
	private $_canBeCut;
	
	/**
	 * 标记被砍伐状态
	 * @var boolean
	 */
	private $_beCut = false;
	
	/**
	 * 标记结果
	 * @var string
	 */
	const  HAD_GAINS = 'gains';
	
	//定义树的成长状态常量
	const SEED = '种子';
	const SEEDLING = '小苗';
	const LITTLE_TREE = '小树';
	const BIG_TREE = '大树';
	
	/**
	 * 状态
	 */
	private $_status;
	
	private $_isSingle = false;
	
	private static $_singleoneObjects = array();
	
	/**
	 * 构造方法
	 * @param int $userId 玩家ID
	 * @param int $treeId 树的id
	 * @access protect
	 */
	protected function __construct( $userId , $treeId , $lock = false )
	{
		$db = & Common::getDB( $this->userId );
		$this->data = array();
		$this->data = $db->find( 'lw_tree' , array( 'tid' => $treeId ) );
		$this->_isSingle = true;
		parent::__construct( $userId , 'tree_'. $treeId , $lock );
	}
	
	/**
	 * 利用对象仓库来存储实例，减少内存消耗
	 * @param 用户ID $userId int
	 * @param 树的ID $tid int
	 * @param 是否加写锁  $lock boolean
	 * @return TreeModel
	 */
	public static function getInstance( $userId , $tid , $lock = false )
	{
		if( !isset( self::$_singleoneObjects[ $tid ] ) )
		{
			self::$_singleoneObjects[ $tid ] = new TreeModel( $userId , $tid , $lock );
		}
		
		if( !self::$_singleoneObjects[ $tid ]->isLocked() )
		{
			self::$_singleoneObjects[ $tid ] = new TreeModel( $userId , $tid , $lock );
		}
		
		if( $lock )
		{
			ObjectStorage::register( self::$_singleoneObjects[ $tid ] );
		}
		return self::$_singleoneObjects[ $tid ];
	}
	
	public function __destruct()
	{
		$this->save();
		parent::__destruct();
	}
	
	/**
	 * 树木状态可砍伐次数
	 * @var array( {状态} : int //次数 )
	 */
	private $_canBeCutNum;
	/**
     * @return the $_gainsValue
     */
    public function getFriutNum ()
    {
		return $this->data['friutNum'];
    }

	/**
	 * @return the $_gainsGrowthValue
	 */
	public function getFruitgrowthValue() 
	{
		return $this->data['fruitgrowthValue'];
	}

	/**
	 * @return the $_died
	 */
	public function getDied( $key = null ) 
	{
		return $this->data['isDied'];
	}

	/**
	 * @param boolean $_died
	 */
	public function setDied( $_died ) 
	{
		if( $_died )
		{
			//当树木变成死亡状态时，果实会变为0
			$this->_gainsValue = 0;
		}
		$this->data['isDied'] = $_died;
		$this->updateToDb( 'lw_tree', DATA_ACTION_UPDATE , array( 'isDied' => $_died ) );
	}

	/**
	 * @return the $_wizened
	 */
	public function getDry() 
	{
		return $this->data['isDry'];
	}

	/**
	 * @param boolean $_wizened
	 */
	public function setDry($_wizened) 
	{
		if( $_wizened )
		{
			//如果树在变成干枯时，果实的数量会减少一半，并且向下取整
			$this->data['fruitNum'] = floor( $this->data['fruitNum'] / 2 );
		}
		$this->data['isDry'] = $_wizened;
		$this->updateToDb( 'lw_tree', DATA_ACTION_UPDATE , $this->data );
	}

	/**
	 * @return the $_canBeCut
	 */
	public function getCanBeCut() 
	{
		return $this->data['canBeCut'];
	}

	/**
	 * @param int $_canBeCut
	 */
	public function setCanBeCut($_canBeCut) 
	{
		$this->data['canBeCut'] = $_canBeCut;
		$this->updateToDb( 'lw_tree', self::DATA_ACTION_UPDATE , $this->data );
	}

	/**
	 * 设置砍伐状态
	 * @param boolean $_beCut
	 */
	public function setBeCut($_beCut) 
	{
		$this->_beCut = $_beCut;
	}
	
	/**
	 * 获取砍伐状态
	 * @return boolean
	 */
	public function getBeCut()
	{
		return $this->_beCut;
	}

	/**
     * @return the $_growthTimes
     */
    public function getGrowthTimes ()
    {
        return $this->data['growthTimes'];
    }

	/**
	 * 获取树的当前状态
	 * @return string
	 */
	public function getStatus()
	{
		if( $this->data['fruitNum'] > 0 )
		{
			return TreeModel::HAD_GAINS;
		}
		$statusArr = Common::getConfig( 'treeStatus' );
		foreach ( $statusArr as $key => $value )
		{
			if( $this->data['growthValue'] >= $value[ 'min' ] && $this->data['growthValue'] < $value[ 'max' ] )
			{
				return $key;
			}
		}
	}
	
	/**
	 * 树的成长机制
	 * @return boolean 是否更改状态
	 */
	public function grow()
	{
	    $this->data['growthTimes']++;
		$oldStatus = $this->getStatus();
		/*树的成长值算法修改为log( 生长次数 , 1.0345 )，精度为小数点后1位，当树的成长值大于300时，停止生长*/
		$this->data['growthValue'] = round( log( $this->getGrowthTimes() , Common::getConfig( 'grow' )) , 1 );
		$this->data['growthValue'] = $this->data['growthValue'] > 300 ? 300 : $this->data['growthValue'];
	    if ( $this->getStatus() == TreeModel::BIG_TREE )
		{
		    //当树长到大树后，每次成长就会增加1点果实生长值
			$this->data['fruitgrowthValue'] += 1;
			if( $this->data['fruitgrowthValue'] >= 20 )
			{
				//当树的果实生长值到达20时，树的果实数量为成长值/4并向上取整
				$this->data['fruitNum'] = ceil( $this->data['fruitgrowthValue'] / 4 );
				$this->data['fruitgrowthValue'] = 0;
			}
		}
		$newStatus = $this->getStatus();
		$hadChangeStatus = ( $oldStatus != $newStatus );
		if( $hadChangeStatus )
		{
			$canBuCutArr = Common::getConfig( 'tree_cut_times' );
			$this->data['canBeCut'] = $$canBuCutArr[ $newStatus ];
		}
		$this->updateToDb( 'lw_tree', DATA_ACTION_UPDATE , $this->data );
		return $hadChangeStatus;
	}
	
	/**
	 * 收获果实
	 */
	public function getFruit()
	{
		if( $this->data['fruitNum'] >0 )
		{
			//果实数减1
			$this->data['fruitNum'] -= 1;
			$this->updateToDb( 'lw_tree', DATA_ACTION_UPDATE , $this->data );
		}	
	}
	
	/**
	 * 掉下一颗种子
	 * @param int $userId 玩家id
	 */
	public static function addSeed( $userId )
	{
		$data = array(
			'growthValue' => Common::getConfig( 'default_growthValue' ),
			'userId' => $userId,
		);
		$db = Common::getDB();
		$tid = $db->add( 'lw_tree' , $data );
		if ( $tid !== false )
		{
			ForestModel::getInstance( $userId )->addTree( $tid );
		}
	}
	
	/**
	 * 树被砍
	 */
	public function beCut()
	{
		if ( $this->data['canBeCut'] > 0 )
		{
			$this->data['canBeCut']--;
			if ( $this->data['canBeCut'] == 0 )
			{
				$this->updateToDb( 'lw_tree' , DATA_ACTION_DELETE , array( 'tid' => $this->data['tid'] ) );
			}
			else  
			{
				$this->updateToDb( 'lw_tree' , DATA_ACTION_UPDATE , $this->data );
			}
			return true;
		}
		return false;
	}
	
	public function getData()
	{
		if ( is_array( $this->data ) )
		{
			return json_encode( $this->data );
		}
	}
	
	protected function formatToDBData( $table , $data )
	{
		return $data;
	}
	
	protected function formatFromDBData( $table , $data )
	{
		return $data;
	}
	
	protected function emptyDataWhenloadFromDB( $table )
	{
		return false;
	}
}
?>